package Client;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;

//import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
//import javax.swing.ListModel;

public class MainWindow extends JFrame {

	private static final long serialVersionUID = 1L;

	private HashMap<String, JButton> windowButtons;
	//private HashMap<String, SubjectWindow> subjectWindows;
	private HashMap<String, TabbedSubject> subjectTabbed;
	/**
	 * tab of the subjects
	 */
	private JTabbedPane tabbedSubject;
	
	/**
	 * text show in button, use this form to permit other languages<br/>
	 * 0:ok; 1:ConnectToSubject; 2:AddSubject
	 */
	private String[] nameButtons = {"Ok", "Se connecter au forum", "Ajouter forum"};

	private JPanel topPanel;
	private JPanel midPanel;
	private JPanel bottomPanel;

	private BorderLayout mainLayout;
	private GridLayout bottomLayout;
	private GridLayout midLayout;
	private GridLayout topLayout;

	private JTextField pseudoField;
	private JTextField newSubjectField;
	private JList<String> subjectNameList;
	//private ListModel<String> subjectModel;

	private JLabel chooseNameLabel;

	final HashSet<String> subjects;
	private Client client;

	public MainWindow(Client c) {
		client = c;
		
		subjects = new HashSet<String>();
		subjects.addAll(client.getSubjects());
		
		windowButtons = new HashMap<String, JButton>();
		//subjectWindows = new HashMap<String, SubjectWindow>();
		subjectTabbed = new HashMap<String,TabbedSubject>();
		tabbedSubject = new JTabbedPane();

		topPanel = new JPanel();
		midPanel = new JPanel();
		bottomPanel = new JPanel();
		
		mainLayout = new BorderLayout();
		topLayout = new GridLayout(1,0);
		midLayout = new GridLayout();
		bottomLayout = new GridLayout(1,0);
		
		pseudoField = new JTextField("");
		newSubjectField = new JTextField("");
		
		subjectNameList = new JList<String>();
		//subjectModel = new DefaultListModel<String>();
		//subjectNameList.setModel(subjectModel);

		this.setLayout(mainLayout);

		/*
		 * Notice this is important to build the button before build the component of the window
		 */
		buildButtons();
		
		/*
		 * Components of the main window, which is cool
		 */
		buildTop();
		buildMid();
		buildBottom();
		
		/*
		 * The window is set to 16/9 format, you must speficiate just the width
		 */
		int a = 820;
		this.setMinimumSize(new Dimension(a, a*9/16));
		
		this.repaint();
	}
	
	private void buildTop(){
		this.add(topPanel, BorderLayout.NORTH);
		topPanel.setLayout(topLayout);
		chooseNameLabel = new JLabel("Choisir pseudo");
		topPanel.add(chooseNameLabel);
		topPanel.add(pseudoField);
		topPanel.add(windowButtons.get(nameButtons[0]));
	}
	
	private void buildMid(){
		midPanel.setLayout(midLayout);
		midPanel.add(tabbedSubject);
		JPanel westPanel = new JPanel(new BorderLayout());
		westPanel.add(new JLabel("List of the subject discussion"), BorderLayout.NORTH);
		westPanel.add(subjectNameList, BorderLayout.CENTER);
		this.add(westPanel, BorderLayout.WEST);
		this.add(midPanel, BorderLayout.CENTER);
		updateSubjects();
	}
	
	public void updateSubjects(){
		Vector<String> v = new Vector<String>(client.getSubjects());
		subjectNameList.setListData(v);
	}
	
	private void buildBottom(){
		this.add(bottomPanel, BorderLayout.SOUTH);
		bottomPanel.setLayout(bottomLayout);
		bottomPanel.add(windowButtons.get(nameButtons[1]));
		bottomPanel.add(windowButtons.get(nameButtons[2]));
		bottomPanel.add(newSubjectField);
	}

	private void buildButtons() {
		for(String s: nameButtons){
			windowButtons.put(s, new JButton(s));
		}
		
		buildActionListener();
	}
	
	/**
	 * Show a pane with the subject ask
	 * @param name: name of the subject which be display
	 */
	private void addSubjectPane(String subjectName){
		if(!subjectTabbed.containsKey(subjectName)){
			subjectTabbed.put(subjectName, new TabbedSubject(this, subjectName));
			this.tabbedSubject.addTab(subjectName, null, subjectTabbed.get(subjectName), null); 
		}
	}

	/**
	 * Disable a pane of this subject
	 * @param name: name of the subject which be display
	 */
	private void removeSubjectPane(String name){
		tabbedSubject.remove(subjectTabbed.get(name));
		subjectTabbed.remove(name);
	}
	
	private void setName(){
		client.setName(pseudoField.getText());
		chooseNameLabel.setText("Bonjour "+client.getName());
		pseudoField.setVisible(false);
		windowButtons.get(nameButtons[0]).setVisible(false);
	}
	
	private void createSubject(){
		String subjectName = newSubjectField.getText();
		if(!subjectName.isEmpty()){
			client.addSubjectFromWindow(newSubjectField.getText());
			newSubjectField.setText("");
		}
	}
	
	private void openSubject(){
		//Open the selected subject's window
		String subjectSelect = subjectNameList.getSelectedValue();
		if(!subjectSelect.isEmpty()){
			addSubjectPane(subjectSelect);
			try {
				client.openSubject(subjectSelect);
			} catch (RemoteException e1) {
				e1.printStackTrace();
			}
		}		
	}

	private void buildActionListener() {
		/*
		 * Set a name for the client if he doesn't want to be anonymous
		 */
		windowButtons.get(nameButtons[0]).addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setName();
			}
		});
		
		/*
		 * Open the selected subject's window
		 */
		windowButtons.get(nameButtons[1]).addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openSubject();		
			}
		});
		
		/*
		 * create a new subject on the server
		 */
		windowButtons.get(nameButtons[2]).addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				createSubject();
			}
		});
		
	}

	public void publish(String sujet, String message) {
		//subjectWindows.get(sujet).appendText(message);
		subjectTabbed.get(sujet).appendText(message);
	}

	public void diffuserMessage(String name, String text) throws RemoteException {
		client.diffuserMessage(name, text);
	}
	
	public void closeSubject(String nameSubject){
		removeSubjectPane(nameSubject);
		client.closeSubject(nameSubject);
	}

}
